<template>
  <div>
      <el-form ref="form" label-width="80px" :model="spu">
        <el-form-item label="SPU名称">
            <el-input placeholder="SPU名称" v-model="spu.spuName"></el-input>
        </el-form-item>
        <el-form-item label="品牌">
            <el-select placeholder="请选择品牌" v-model="spu.tmId">
              <el-option :label="tm.tmName" :value="tm.id" v-for="(tm,index) in tradeMarkList" :key="tm.id"></el-option>
            </el-select>
        </el-form-item>
        <el-form-item label="SPU描述">
            <el-input type="textarea" rows="4" placeholder="SPU描述" v-model="spu.description"></el-input>
        </el-form-item>
        <el-form-item label="SPU图片">
            <!-- 上传图片 
                action：图片上传地址
                list-type：文件列表的类型
                on-preview：图片预览的时候会触发
                on-remove：当删除图片会触发
                file-list：照片墙图片列表
            -->
            <el-upload
                action="/index/admin/product/upload"
                list-type="picture-card"
                :on-preview="handlePictureCardPreview"
                :on-remove="handleRemove"
                :on-success="handleSuccess"
                :file-list="spuImageList">
                <i class="el-icon-plus"></i>
            </el-upload>
            <el-dialog :visible.sync="dialogVisible">
                <img width="100%" :src="dialogImageUrl" alt="">
            </el-dialog>
        </el-form-item>
        <el-form-item label="销售属性">
            <el-select :placeholder="`还有${unSelectSaleAttr.length}项未选择`" v-model="attrIdAndName">
              <el-option :label="unselect.name" :value="`${unselect.id}:${unselect.name}`" v-for="(unselect,index) in unSelectSaleAttr" :key="unselect.id"></el-option>
            </el-select>
            <el-button type="primary" icon="el-icon-plus" style="margin:0 10px" :disabled="!attrIdAndName" @click="addSaleAttr">添加销售属性</el-button>
            <!-- 展示当前spu属于自己的销售属性 -->
            <el-table style="width: 100%;margin:10px 0" border :data="spu.spuSaleAttrList">
              <el-table-column label="序号" width="80px" type="index" align="center"></el-table-column>
              <el-table-column label="属性名" width="100px" prop="saleAttrName"></el-table-column>
              <el-table-column label="属性值名称列表" width="width" prop="prop">
                  <template slot-scope="{row,$index}">
                    <el-tag :key="tag.id" v-for="(tag,index) in row.spuSaleAttrValueList" closable :disable-transitions="false" @close="row.spuSaleAttrValueList.splice(index,1)">
                        {{tag.saleAttrValueName}}
                    </el-tag>
                    <!-- input button只存在一个 -->
                    <el-input class="input-new-tag" v-if="row.inputVisible" v-model="row.inputValue" ref="saveTagInput" size="small" @blur="handleInputConfirm(row)"></el-input>
                    <el-button v-else size="mini" class="button-new-tag" icon="el-icon-plus" @click="addSaleAttrValue(row)" circle></el-button>
                  </template>
              </el-table-column>
              <el-table-column label="操作" width="width" prop="prop">
                  <template slot-scope="{row,$index}">
                    <el-button type="danger" icon="el-icon-delete" size="mini" @click="spu.spuSaleAttrList.splice($index,1)"></el-button>
                  </template>
              </el-table-column>
            </el-table>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="addOrUpdateSpu">保存</el-button>
            <el-button @click="cancel">取消</el-button>
        </el-form-item>
      </el-form>
  </div>
</template>

<script>
export default {
    name:'SpuForm',
    data() {
        return {
            dialogImageUrl: '',
            dialogVisible: false,
            //存储spu信息
            spu:{
                "category3Id": 0, //三级分类的id
                "description": "", //描述
                "id": 0, //spuid
                // spu图片信息
                "spuImageList": [
                    // {
                    // "id": 0,
                    // "imgName": "",
                    // "imgUrl": "",
                    // "spuId": 0
                    // }
                ],
                // spu名称
                "spuName": "",
                // spu销售属性与属性值的收集
                "spuSaleAttrList": [
                    // {
                    // "baseSaleAttrId": 0,
                    // "id": 0,
                    // "saleAttrName": "",
                    // "spuId": 0,
                    // "spuSaleAttrValueList": [
                    //     {
                    //     "baseSaleAttrId": 0,
                    //     "id": 0,
                    //     "isChecked": "",
                    //     "saleAttrName": "",
                    //     "saleAttrValueName": "",
                    //     "spuId": 0
                    //     }
                    // ]
                    // }
                ],
                // 品牌的id
                "tmId": ""
            }, 
            tradeMarkList:[], //存储品牌信息
            spuImageList:[], //存储spu图片的数据
            baseSaleAttrList:[], //存储销售属性数据
            attrIdAndName:'', //收集未选择的销售属性的id
        }
    },
    computed:{
        // 计算出还未选择的销售属性
        unSelectSaleAttr(){
            // 共3个 baseSaleAttrList里
            // 当前spu拥有的销售属性 spu.spuSaleAttrList
            // 使用数组过滤，并返回一个新数组
            let result = this.baseSaleAttrList.filter(item=>{
                return this.spu.spuSaleAttrList.every(item1=>{
                    return item.name!=item1.saleAttrName;
                })
            });
            return result;
        }
    },
    methods: {
      // 照片墙删除某一个图片时的回调  
      // file:代表删除的那张图片
      // fileList：删除图片后，剩余其他图片  
      handleRemove(file, fileList) {
        // 收集照片墙图片的数据
        // 对于照片墙中已有的图片，有我们多余加的name和url字段，对于服务器而言不需要这两个，提交的时候需要处理
        this.spuImageList = fileList;
      },
      // 照片墙图片上传成功的参数
      // file:代表上传成功的那张图片
      // fileList：新增图片后所有图片
      handleSuccess(response,file,fileList){
        // 对于新增的图片，也有name和url字段
        this.spuImageList = fileList;
      },
      // 照片墙图片预览的回调  
      handlePictureCardPreview(file) {
        this.dialogImageUrl = file.url;
        this.dialogVisible = true;
      },
      // 初始化SpuForm数据
      async initSpuData(spu){
        // 获取spu信息
        let spuResult = await this.$API.spu.reqSpu(spu.id);
        if(spuResult.code==200){
            this.spu = spuResult.data;
        }
        // 获取品牌的信息
        let tradeMarkResult = await this.$API.spu.reqTradeMarkList();
        if(tradeMarkResult.code==200){
            this.tradeMarkList = tradeMarkResult.data;
        }
        // 获取spu图片信息
        let spuImageResult = await this.$API.spu.reqSpuImageList(spu.id);
        if(spuImageResult.code==200){
            // 照片墙数组元素要求有name和url字段
             let listArr = spuImageResult.data;
             listArr.forEach(item => {
                 item.name = item.imgName;
                 item.url = item.imgUrl;
             });
             this.spuImageList = listArr;
        }
        // 获取所有销售属性信息
        let baseSaleAttrResult = await this.$API.spu.reqBaseSaleAttrList();
        if(baseSaleAttrResult.code==200){
            this.baseSaleAttrList = baseSaleAttrResult.data;
        }
      },
      // 添加销售属性按钮回调
      addSaleAttr(){
        // 把收集到的销售属性数据进行分割
        const [baseSaleAttrId,saleAttrName] = this.attrIdAndName.split(':');
        // 向spu对象的spuSaleAttrList数组中添加新的销售属性
        let newSaleAttr = {baseSaleAttrId,saleAttrName,spuSaleAttrValueList:[]};
        // 添加新的销售属性
        this.spu.spuSaleAttrList.push(newSaleAttr);
        // 清空数据
        this.attrIdAndName = '';
      },
      // 添加按钮的回调
      addSaleAttrValue(row){
        // 通过inputVisible控制
        this.$set(row,'inputVisible',true);
        // 收集新增的销售属性值
        this.$set(row,'inputValue','');
      },
      // input失去焦点事件
      handleInputConfirm(row){
        const {baseSaleAttrId,inputValue} = row;
        // 新增的销售属性值的名称不能为空
        if(inputValue.trim()==''){
          this.$message('属性值不能为空');
          return;
        }
        // 新增的销售属性值的名称不能重复
        let result = row.spuSaleAttrValueList.every(item=>item.saleAttrValueName==inputValue);
        if(result&&row.spuSaleAttrValueList.length!=0){
          this.$message('属性值不能重复');
          return;
        }
        // 新增的销售属性值
        let newSaleAttrValue = {
          baseSaleAttrId,
          saleAttrValueName:inputValue
        }
        row.spuSaleAttrValueList.push(newSaleAttrValue);
        // 修改inputVisible
        row.inputVisible = false;
      },
      // 保存按钮回调
      async addOrUpdateSpu(){
        // 整理参数：需要整理照片墙数据
        // 对于图片需要携带imageName与imageUrl字段
        this.spu.spuImageList = this.spuImageList.map(item=>{
          return{
            imageName:item.name,
            // 新图在response里 老图在url里
            imageUrl:(item.response && item.response.data) || item.url
          }
        });
        // 发请求
        let result = await this.$API.spu.reqAddOrUpdateSpu(this.spu);
        if(result.code==200){
          this.$message.success('保存成功');
          // 通知父组件回到场景0
          this.$emit('changeScene',0);
        }
        // 清除数据
        Object.assign(this._data,this.$options.data());
      },
      // 点击添加spu按钮时发请求的函数
      async addSpuData(category3Id){
        // 收集三级分类id
        this.spu.category3Id = category3Id;
        // 获取品牌的信息
        let tradeMarkResult = await this.$API.spu.reqTradeMarkList();
        if(tradeMarkResult.code==200){
            this.tradeMarkList = tradeMarkResult.data;
        }
        // 获取所有销售属性信息
        let baseSaleAttrResult = await this.$API.spu.reqBaseSaleAttrList();
        if(baseSaleAttrResult.code==200){
            this.baseSaleAttrList = baseSaleAttrResult.data;
        }
      },
      // 取消按钮
      cancel(){
        // 通知父组件切换场景
        this.$emit('changeScene',0);
        // 清理数据
        // Object.assign：es6新增方法，可以合并对象
        // this._data：响应式数据
        // this.$options.data()：当前组件配置对象的data函数，返回的响应式数据是空的
        Object.assign(this._data,this.$options.data());
      }
    }
}
</script>

<style>
  .el-tag + .el-tag {
    margin-left: 10px;
  }
  .button-new-tag {
    margin-left: 10px;
    /* height: 32px;
    line-height: 30px; */
    padding-top: 0;
    padding-bottom: 0;
  }
  .input-new-tag {
    width: 90px;
    margin-left: 10px;
    vertical-align: bottom;
  }
</style>